#include <types.h>
#include <sys_config.h>
#include <retcode.h>
#include <api/libc/string.h>
#include <api/libc/printf.h>
#include <osal/osal.h>
#include <hld/hld_dev.h>
#include <hld/dis/VPO.h>
#include <hld/decv/vdec_driver.h>
#include <hld/decv/decv.h>
#include <hld/deca/deca_dev.h>
#include <hld/deca/deca.h>
#include <hld/snd/snd_dev.h>
#include <hld/snd/snd.h>

#include <api/libimagedec/imagedec.h>
#include <api/libmp/pe.h>
#include "music/plugin.h"
#include "music/music_engine.h"
#include "image/image_engine.h"
#if 0
#include "image/plus720x576_420.h"

#include "image/h1_720x576h.264.h"
#endif

#define ENABLE_PE_CACHE
#ifdef NETWORK_SUPPORT
#include <api/libnet/libnet.h>
#include <api/libtcpip/lwip/inet.h>
extern FILE *url_open(const char *path, unsigned char* buffer, unsigned int buf_len, unsigned int offset);
extern size_t url_read(void *ptr, size_t size, size_t nmemb, FILE *stream);
extern size_t url_close(FILE * fp);
extern off_t url_tell(FILE * stream);
extern int url_eof(FILE * stream);
extern INT32 url_seek(FILE * stream, off_t offset, int fromwhere);
#endif
#ifdef MP4_CONTAINER
#include "av_player/av_player.h"
extern P_HANDLE g_mp4_av_player_handle;
#endif
struct pe_feature_cfg g_mp_feature_cfg;
static UINT8 pe_init_time = 0;
static struct pe_music_cfg g_pe_music_cfg;	//for release the memory in pe_cleanup

#ifdef SUPPORT_ES_PLAYER
FILE *ali_stream_open(const char *path, unsigned char* buffer, unsigned int buf_len, unsigned int offset);
size_t ali_stream_close(FILE * fp);
size_t ali_stream_read(void *ptr, size_t size, size_t nmemb, FILE *stream);
int ali_stream_seek(FILE *stream, off_t offset, int whence);
off_t ali_stream_tell(FILE *stream);
int is_ali_stream(char *file);
int is_es_stream(char *file);
int ali_stream_end(FILE *stream);
#endif
//################################################################################
//## wrapper for music engine

//#define MUSIC_DEBUG
#ifdef MUSIC_DEBUG
    #define MUSIC_PRINTF libc_printf
#else
    #define MUSIC_PRINTF(...) do{}while(0)
#endif

//#define IMAGE_DEBUG
#ifdef IMAGE_DEBUG
    #define IMAGE_PRINTF libc_printf
#else
    #define IMAGE_PRINTF(...) do{}while(0)
#endif
OSAL_ID music_engine_flag = OSAL_INVALID_ID;
OSAL_ID music_engine_task_id = OSAL_INVALID_ID;

#define MUSIC_ENGINE_CMD_PLAY    0X00000001
#define MUSIC_ENGINE_CMD_STOP    0X00000002
#define MUSIC_ENGINE_CMD_SEEK    0X00000004
#define MUSIC_ENGINE_CMD_PAUSE   0X00000008
#define MUSIC_ENGINE_CMD_TIME_GET 0X00000010
#define MUSIC_ENGINE_CMD_SONG_INFO_GET 0X00000020
#define MUSIC_ENGINE_CMD_DECODER_INFO_GET 0X00000040
#define MUSIC_ENGINE_CMD_SONG_INFO_SET 0X00000080

#define MUSIC_ENGINE_CMD_TASK_EXIT 0X00000100


#define MUSIC_ENGINE_CMD_PLAY_OK    0X00010000
#define MUSIC_ENGINE_CMD_STOP_OK    0X00020000
#define MUSIC_ENGINE_CMD_SEEK_OK    0X00040000
#define MUSIC_ENGINE_CMD_PAUSE_OK   0X00080000
#define MUSIC_ENGINE_CMD_TIME_GET_OK 0X00100000
#define MUSIC_ENGINE_CMD_SONG_INFO_GET_OK 0X00200000
#define MUSIC_ENGINE_CMD_DECODER_INFO_GET_OK 0X00400000
#define MUSIC_ENGINE_CMD_SONG_INFO_SET_OK 0X00800000

#define MUSIC_ENGINE_CMD_TASK_EXIT_OK 0X01000000


//static char *g_filename_p = NULL;
static char g_filename_p[1024] = {0};
static int music_play_rt = 0;
static int seek_time = 0;
static int play_time = 0;
//static MusicInfo *g_song_info_p = NULL;
static MusicInfo g_song_info;
static int g_song_info_get_rt = 0;
//static DecoderInfo *g_decoder_info_p = NULL;
static DecoderInfo g_decoder_info;

void music_engine_cmd_proc_task()
{
    UINT32 flgptn = 0;
    OSAL_ER rlt;

    while(1)
    {
//        MUSIC_PRINTF("waiting_cmd...\n");
        rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_PLAY|MUSIC_ENGINE_CMD_STOP|MUSIC_ENGINE_CMD_SEEK|
                                        MUSIC_ENGINE_CMD_PAUSE|MUSIC_ENGINE_CMD_TIME_GET|MUSIC_ENGINE_CMD_SONG_INFO_GET|
                                        MUSIC_ENGINE_CMD_DECODER_INFO_GET|MUSIC_ENGINE_CMD_SONG_INFO_SET|MUSIC_ENGINE_CMD_TASK_EXIT,
                                        OSAL_TWF_ORW,OSAL_WAIT_FOREVER_TIME);

        if(OSAL_E_OK == rlt)
        {
//            MUSIC_PRINTF("waited_cmd\n");

            if(MUSIC_ENGINE_CMD_TASK_EXIT & flgptn)
            {
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT_OK);

                return;
            }

            if(MUSIC_ENGINE_CMD_PLAY & flgptn)
            {
                MUSIC_PRINTF("music_engine_play_cmd\n");
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PLAY);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_PLAY_OK);
                music_play_rt = music_engine_play(g_filename_p);
            }

            if(MUSIC_ENGINE_CMD_STOP & flgptn)
            {
                MUSIC_PRINTF("music_engine_stop_cmd\n");

                music_engine_stop();
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_STOP);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_STOP_OK);
            }

            if(MUSIC_ENGINE_CMD_SEEK & flgptn)
            {
                MUSIC_PRINTF("music_engine_seek_cmd\n");

                music_engine_seek(seek_time);
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SEEK);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_SEEK_OK);
            }

            if(MUSIC_ENGINE_CMD_PAUSE & flgptn)
            {
                MUSIC_PRINTF("music_engine_pause_cmd\n");

                music_engine_pause();
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE_OK);
            }

            if(MUSIC_ENGINE_CMD_TIME_GET & flgptn)
            {
//                MUSIC_PRINTF("music_engine_time_get_cmd\n");

                play_time = music_engine_get_time();
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET_OK);
            }

            if(MUSIC_ENGINE_CMD_SONG_INFO_GET & flgptn)
            {
                MUSIC_PRINTF("music_engine_song_info_get_cmd\n");

                g_song_info_get_rt = music_engine_get_song_info(g_filename_p, &g_song_info);
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET_OK);
            }

            if(MUSIC_ENGINE_CMD_DECODER_INFO_GET & flgptn)
            {
                MUSIC_PRINTF("music_engine_decoder_info_get_cmd\n");

                music_engine_get_decoder_info(g_filename_p, &g_decoder_info);
                osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET);
                osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET_OK);
            }

            if(MUSIC_ENGINE_CMD_SONG_INFO_SET & flgptn)
            {
            }
        }
        else
        {
            SDBBP();
        }
    }
}

int music_init(struct pe_music_cfg *pe_music_cfg)
{
    OSAL_T_CTSK music_engine_task_param;

    music_engine_flag = osal_flag_create(0x00000000);
    if(OSAL_INVALID_ID == music_engine_flag)
    {
        SDBBP();
    }

    music_engine_task_param.task = music_engine_cmd_proc_task;
    music_engine_task_param.itskpri=OSAL_PRI_HIGH;
    music_engine_task_param.quantum=10 ;
    music_engine_task_param.stksz = 0x4000 ;
    music_engine_task_param.para1=0;
    music_engine_task_param.para2=0 ;
    music_engine_task_param.name[0] = 'A';
    music_engine_task_param.name[1] = 'E';
    music_engine_task_param.name[2] = 'N';

    music_engine_task_id = osal_task_create(&music_engine_task_param);
    if(OSAL_INVALID_ID == music_engine_task_id)
    {
        SDBBP();
    }

	return music_engine_init(pe_music_cfg);
}

void music_release()
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT_OK,OSAL_TWF_ANDW, 5000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_play_cmd_task_exit_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT_OK);
        return -1;
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TASK_EXIT_OK);
    music_engine_task_id = OSAL_INVALID_ID;
    if(OSAL_INVALID_ID != music_engine_flag)
    {
        osal_flag_delete(music_engine_flag);
        music_engine_flag = OSAL_INVALID_ID;
    }

	music_engine_release();
}


int music_play(char *filename)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

	MEMSET(g_filename_p,0,1024);
    MEMCPY(g_filename_p,filename,1024);
//    g_filename_p = filename;

    MUSIC_PRINTF("music_play_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_PLAY);
    rlt = osal_flag_wait(&flgptn,music_engine_flag, MUSIC_ENGINE_CMD_PLAY_OK,OSAL_TWF_ANDW, 5000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_play_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PLAY);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PLAY_OK);
        return -1;
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PLAY_OK);

    MUSIC_PRINTF("music_play_cmd_set<--\n");

	return 0;//music_engine_play(filename);
}

void music_seek(int time)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    seek_time = time;

    MUSIC_PRINTF("music_seek_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_SEEK);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_SEEK_OK,OSAL_TWF_ANDW,5000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_seek_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SEEK);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SEEK_OK);
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SEEK_OK);

    MUSIC_PRINTF("music_seek_cmd_set<---\n");

    return;
}

void music_stop(void)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MUSIC_PRINTF("music_stop_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_STOP);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_STOP_OK,OSAL_TWF_ANDW, 5000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_stop_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_STOP);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_STOP_OK);
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_STOP_OK);

    MUSIC_PRINTF("music_stop_cmd_set<---\n");

    return;

}

void music_pause(void)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MUSIC_PRINTF("music_pause_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_PAUSE_OK,OSAL_TWF_ANDW,1000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_pause_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE_OK);
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_PAUSE_OK);

    MUSIC_PRINTF("music_pause_cmd_set<---\n");

    return;

}

int music_get_time(void)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MUSIC_PRINTF("music_time_get_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET_OK,OSAL_TWF_ANDW,200);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_time_get_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET_OK);
        return 0;
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_TIME_GET_OK);

    MUSIC_PRINTF("music_time_get_cmd_set<---\n");

    return play_time;
}


void music_set_eq(int on, float preamp, float *bands)
{
	music_engine_set_eq(on, preamp, bands);
}

int music_get_song_info(char * filename, MusicInfo *music_info)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MEMSET(g_filename_p,1024,0);
    MEMCPY(g_filename_p,filename,1024);
//    g_filename_p = filename;
//    g_song_info_p = music_info;

    MUSIC_PRINTF("music_song_info_get_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET_OK,OSAL_TWF_ANDW,2000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_song_info_get_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET_OK);
        return -1;
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_SONG_INFO_GET_OK);

    MEMCPY(music_info,&g_song_info,sizeof(g_song_info));

    MUSIC_PRINTF("music_time_song_info_get_set<---\n");

    return g_song_info_get_rt;
}

int music_get_decoder_info(char * filename, DecoderInfo *decoder_info)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MEMSET(g_filename_p,1024,0);
    MEMCPY(g_filename_p,filename,1024);

//    g_filename_p = filename;
//    g_decoder_info_p = decoder_info;

    MUSIC_PRINTF("music_decoder_info_get_cmd_set-->\n");

    osal_flag_set(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET);
    rlt = osal_flag_wait(&flgptn,music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET_OK,OSAL_TWF_ANDW,2000);
    if(OSAL_E_OK != rlt)
    {
        MUSIC_PRINTF("music_decoder_info_get_cmd_rps_fail\n");

        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET);
        osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET_OK);
        return -1;
    }
    osal_flag_clear(music_engine_flag,MUSIC_ENGINE_CMD_DECODER_INFO_GET_OK);

    MEMCPY(decoder_info,&g_decoder_info,sizeof(g_decoder_info));

    MUSIC_PRINTF("music_time_decoder_info_get_set<---\n");

    return 0;
}

int music_set_other_info(UINT32 cmd, UINT32 param1)
{
	return music_engine_set_other_info(cmd, param1);
}


#define IMAGE_ENGINE_CMD_VPO_RECT_RESTORE   0X00000001
#define IMAGE_ENGINE_CMD_ABORT              0X00000002
#define IMAGE_ENGINE_CMD_ROTATE             0X00000004
#define IMAGE_ENGINE_CMD_ZOOM               0X00000008
#define IMAGE_ENGINE_CMD_DISP_PARAM_SET     0X00000010
#define IMAGE_ENGINE_CMD_DECODE             0X00000020
#define IMAGE_ENGINE_CMD_DECODE_EX          0X00000040
#define IMAGE_ENGINE_CMD_DISPLAY            0X00000080
#define IMAGE_ENGINE_CMD_INFO_GET           0X00000100
#define IMAGE_ENGINE_CMD_DECODE_NETWORK     0X00000400

#define IMAGE_ENGINE_CMD_TASK_EXIT           0X00000200


#define IMAGE_ENGINE_CMD_VPO_RECT_RESTORE_OK       0X00010000
#define IMAGE_ENGINE_CMD_ABORT_OK                  0X00020000
#define IMAGE_ENGINE_CMD_ROTATE_OK                 0X00040000
#define IMAGE_ENGINE_CMD_ZOOM_OK                   0X00080000
#define IMAGE_ENGINE_CMD_DISP_PARAM_SET_OK         0X00100000
#define IMAGE_ENGINE_CMD_DECODE_OK                 0X00200000
#define IMAGE_ENGINE_CMD_DECODE_EX_OK              0X00400000
#define IMAGE_ENGINE_CMD_DISPLAY_OK                0X00800000
#define IMAGE_ENGINE_CMD_INFO_GET_OK               0X01000000
#define IMAGE_ENGINE_CMD_DECODE_NETWORK_OK         0X04000000

#define IMAGE_ENGINE_CMD_TASK_EXIT_OK               0X02000000



OSAL_ID image_engine_flag = OSAL_INVALID_ID;
OSAL_ID image_engine_task_id = OSAL_INVALID_ID;
static int image_abort_ret = 0;
static int image_rotate_ret = 0;
static UINT8 image_rotate_angle = 0;
//static struct Rect *g_dstRect = NULL;
//static struct Rect *g_srcRect = NULL;
static struct Rect g_dstRect;
static struct Rect g_srcRect;

static int image_zoom_ret = 0;
static struct image_3d_para g_para;
static int g_display_type = 0;
static int image_disp_param_ret = 0;
static struct image_config g_image_dec_cfg;
//static char *g_image_dec_file_name = NULL;
static char g_image_dec_file_name[1024] = {0};
static int image_dec_ret = 0;
static struct image_config g_image_ext_cfg;
static struct image_config g_image_network_cfg;
//static char *image_dec_ex_file_name = NULL;
static char image_dec_ex_file_name[1024] = {0};
static char image_dec_network_file_name[1024] = {0};
static int image_dec_ext_ret = 0;
static int image_dec_network_ret = 0;
static struct image_info g_info;
//static char *g_image_filename = NULL;
static char g_image_filename[1024] = {0};

static int image_info_get_ret = 0;
void image_engine_cmd_proc_task()
{
    UINT32 flgptn = 0;
    OSAL_ER rlt;

    while(1)
    {
//        MUSIC_PRINTF("waiting_cmd...\n");
        rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE|IMAGE_ENGINE_CMD_ABORT|
            IMAGE_ENGINE_CMD_ROTATE|IMAGE_ENGINE_CMD_ZOOM|IMAGE_ENGINE_CMD_DISP_PARAM_SET|IMAGE_ENGINE_CMD_DECODE|
            IMAGE_ENGINE_CMD_DECODE_EX|IMAGE_ENGINE_CMD_DISPLAY|IMAGE_ENGINE_CMD_INFO_GET|IMAGE_ENGINE_CMD_TASK_EXIT|
            IMAGE_ENGINE_CMD_DECODE_NETWORK,
                                        OSAL_TWF_ORW,OSAL_WAIT_FOREVER_TIME);

        if(OSAL_E_OK == rlt)
        {
//            MUSIC_PRINTF("waited_cmd\n");

            if(IMAGE_ENGINE_CMD_TASK_EXIT & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT_OK);

                return;
            }

            if(IMAGE_ENGINE_CMD_VPO_RECT_RESTORE & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE);

            	struct Rect		main_src_rect;
            	struct Rect		main_dst_rect;
            	struct vpo_device *pvpo_sd;

            	vpo_win_onoff((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS),FALSE);
            	pvpo_sd = (struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 1);
            	if(NULL != pvpo_sd)
            		vpo_win_onoff(pvpo_sd, FALSE);	// avoid green screen

            	osal_task_sleep(50);

            	//restore the vop
            	main_src_rect.uStartX = main_src_rect.uStartY = main_dst_rect.uStartX = main_dst_rect.uStartY = 0;
            	main_src_rect.uWidth = PICTURE_WIDTH;
            	main_src_rect.uHeight = PICTURE_HEIGHT;
            	main_dst_rect.uWidth = SCREEN_WIDTH;
            	main_dst_rect.uHeight = SCREEN_HEIGHT;
            	vpo_zoom((struct vpo_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DIS),&main_src_rect,&main_dst_rect);
            	if(NULL != pvpo_sd)
            		vpo_zoom((struct vpo_device *)dev_get_by_id(HLD_DEV_TYPE_DIS, 1),&main_src_rect,&main_dst_rect);

                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE_OK);
            }
            if(IMAGE_ENGINE_CMD_ABORT & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ABORT);
                image_abort_ret = image_engine_abort();
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ABORT_OK);
            }
            if(IMAGE_ENGINE_CMD_ROTATE & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE);
                image_rotate_ret = image_engine_rotate(image_rotate_angle);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE_OK);
            }
            if(IMAGE_ENGINE_CMD_ZOOM & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM);
                image_zoom_ret = image_engine_zoom(&g_dstRect, &g_srcRect);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM_OK);
            }
            if(IMAGE_ENGINE_CMD_DISP_PARAM_SET & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET);
                image_disp_param_ret = image_engine_set_disp_param(g_display_type, &g_para);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET_OK);
            }
            if(IMAGE_ENGINE_CMD_DECODE & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_OK);
                image_dec_ret = image_engine_decode(g_image_dec_file_name, &g_image_dec_cfg);
            }
            if(IMAGE_ENGINE_CMD_DECODE_EX & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX);
                image_dec_ext_ret = image_engine_decode(image_dec_ex_file_name, &g_image_ext_cfg);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX_OK);
            }
            if(IMAGE_ENGINE_CMD_DECODE_NETWORK & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK_OK);

                image_dec_network_ret = image_engine_decode_network(image_dec_network_file_name, &g_image_network_cfg);
            }
            if(IMAGE_ENGINE_CMD_INFO_GET & flgptn)
            {
                osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET);
                image_info_get_ret = image_engine_get_info(g_image_filename, &g_info);
                osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET_OK);
            }
        }
        else
        {
            SDBBP();
        }
    }
}



//################################################################################
//## wrapper for image engine
static int image_init(struct pe_image_cfg *pe_image_cfg)
{
    OSAL_T_CTSK image_engine_task_param;
    image_engine_flag = osal_flag_create(0x00000000);
    if(OSAL_INVALID_ID == image_engine_flag)
    {
        SDBBP();
    }
    image_engine_task_param.task = image_engine_cmd_proc_task;
    image_engine_task_param.itskpri=OSAL_PRI_HIGH;
    image_engine_task_param.quantum=10 ;
    image_engine_task_param.stksz = 0x4000 ;
    image_engine_task_param.para1=0;
    image_engine_task_param.para2=0 ;
    image_engine_task_param.name[0] = 'i';
    image_engine_task_param.name[1] = 'm';
    image_engine_task_param.name[2] = 'g';
    image_engine_task_id = osal_task_create(&image_engine_task_param);
    if(OSAL_INVALID_ID == image_engine_task_id)
    {
        SDBBP();
    }
	int ret;
	ret = image_engine_init(pe_image_cfg);
	return ret;
}
int image_init_network(UINT32 file_addr, UINT32 file_len, struct pe_image_cfg *pe_image_cfg)
{
    OSAL_T_CTSK image_engine_task_param;
    image_engine_flag = osal_flag_create(0x00000000);
    if(OSAL_INVALID_ID == image_engine_flag)
    {
        SDBBP();
    }
    image_engine_task_param.task = image_engine_cmd_proc_task;
    image_engine_task_param.itskpri=OSAL_PRI_HIGH;
    image_engine_task_param.quantum=10 ;
    image_engine_task_param.stksz = 0x4000 ;
    image_engine_task_param.para1=0;
    image_engine_task_param.para2=0 ;
    image_engine_task_param.name[0] = 'i';
    image_engine_task_param.name[1] = 'm';
    image_engine_task_param.name[2] = 'g';
    image_engine_task_id = osal_task_create(&image_engine_task_param);
    if(OSAL_INVALID_ID == image_engine_task_id)
    {
        SDBBP();
    }
	int ret;
	ret = image_engine_init_network(file_addr, file_len, pe_image_cfg);
	return ret;
}
int image_cleanup()
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;
    int ret;

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT_OK,OSAL_TWF_ANDW, 5000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_task_exit_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT_OK);
        return;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_TASK_EXIT_OK);

    image_engine_task_id = OSAL_INVALID_ID;
    if(OSAL_INVALID_ID != image_engine_flag)
    {
        osal_flag_delete(image_engine_flag);
        image_engine_flag = OSAL_INVALID_ID;
    }
	//cleanup the image decoder
	image_engine_abort();
	ret = image_engine_cleanup();
	return ret;
}

void image_restore_vpo_rect()
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;
    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE_OK,OSAL_TWF_ANDW,1000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_vpo_rect_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE_OK);
        return;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_VPO_RECT_RESTORE_OK);
    return;
}

int image_abort()
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ABORT);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_ABORT_OK,OSAL_TWF_ANDW, 5000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_abort_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ABORT);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ABORT_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ABORT_OK);
	return image_abort_ret;
}

int image_rotate(unsigned char rotate_angle)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    image_rotate_angle = rotate_angle;
    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_ROTATE_OK,OSAL_TWF_ANDW,1000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_rotate_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ROTATE_OK);
    return image_rotate_ret;
}

int image_zoom(struct Rect * dstRect, struct Rect * srcRect)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

//    g_dstRect = dstRect;
//    g_srcRect = srcRect;
    MEMSET(&g_dstRect,0,sizeof(g_dstRect));
    MEMSET(&g_srcRect,0,sizeof(g_srcRect));

    MEMCPY(&g_dstRect,dstRect,sizeof(g_dstRect));
    MEMCPY(&g_srcRect,srcRect,sizeof(g_srcRect));

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_ZOOM_OK,OSAL_TWF_ANDW,1000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_zoom_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_ZOOM_OK);
    return image_zoom_ret;
}


int image_2d_to_3d_swap(int display_type,void* pFunc2DTo3D)
{
	int ret;
	ret = image_engine_2d_to_3d_swap(display_type,pFunc2DTo3D);

	return ret;
}

int image_3d_user_option(int output_format, int user_depth, int user_shift, int user_vip)
{
	int ret;
    struct image_3d_para para;
    para.output_format = output_format;
    para.user_depth = user_depth;
    para.user_shift = user_shift;
    para.user_vip = user_vip;
	ret = image_engine_3d_user_option(&para);

	return ret;
}

int image_set_disp_param(int display_type, int output_format, int user_depth, int user_shift, int user_vip)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    g_display_type = display_type;
    g_para.output_format = output_format;
    g_para.user_depth = user_depth;
    g_para.user_shift = user_shift;
    g_para.user_vip = user_vip;

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET_OK,OSAL_TWF_ANDW,1000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_disp_param_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DISP_PARAM_SET_OK);
    return image_disp_param_ret;
}

int image_decode_network(char *file, int mode, int left, int top, int width, int height, unsigned char rotate)
{
	OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    //image_dec_network_file_name = file;
    MEMSET(image_dec_network_file_name,0,1024);
    MEMCPY(image_dec_network_file_name,file,1024);
	MEMSET(&g_image_network_cfg, 0, sizeof(g_image_network_cfg));

	if(mode == IMAGEDEC_REAL_SIZE)
	{
		g_image_network_cfg.decode_mode = IMAGEDEC_REAL_SIZE;
		g_image_network_cfg.src_top = top;
		g_image_network_cfg.src_left = left;
		g_image_network_cfg.src_width= width;
		g_image_network_cfg.src_height = height;
		g_image_network_cfg.rotate = ANG_ORI;
	}
	else if(mode == IMAGEDEC_THUMBNAIL)
	{
		g_image_network_cfg.decode_mode = IMAGEDEC_THUMBNAIL;
		g_image_network_cfg.dest_top = top;
		g_image_network_cfg.dest_left = left;
		g_image_network_cfg.dest_width= width;
		g_image_network_cfg.dest_height = height;
		g_image_network_cfg.rotate = ANG_ORI;
	}
    else if (mode == IMAGEDEC_MULTI_PIC)
    {
        g_image_network_cfg.decode_mode = IMAGEDEC_MULTI_PIC;
		g_image_network_cfg.dest_top = top;
		g_image_network_cfg.dest_left = left;
		g_image_network_cfg.dest_width= width;
		g_image_network_cfg.dest_height = height;
		g_image_network_cfg.rotate = ANG_ORI;
	}
	else if(mode == IMAGEDEC_FULL_SRN)
	{
		g_image_network_cfg.decode_mode = IMAGEDEC_FULL_SRN;
		g_image_network_cfg.dest_top = top;
		g_image_network_cfg.dest_left = left;
		g_image_network_cfg.dest_width= width;
		g_image_network_cfg.dest_height = height;
		g_image_network_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}
	else if(mode == IMAGEDEC_SIZEDEFINE)
	{
		g_image_network_cfg.decode_mode = IMAGEDEC_SIZEDEFINE;
		g_image_network_cfg.dest_top = top;
		g_image_network_cfg.dest_left = left;
		g_image_network_cfg.dest_width= width;
		g_image_network_cfg.dest_height = height;
		g_image_network_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}
	else
	{
		g_image_network_cfg.decode_mode = IMAGEDEC_FULL_SRN;
		g_image_network_cfg.dest_top = top;
		g_image_network_cfg.dest_left = left;
		g_image_network_cfg.dest_width= width;
		g_image_network_cfg.dest_height = height;
		g_image_network_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK_OK,OSAL_TWF_ANDW,5000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_dec_network_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_NETWORK_OK);
	return 0;


}

int image_decode(char *file, int mode, int left, int top, int width, int height, unsigned char rotate)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

//    g_image_dec_file_name = file;
    MEMSET(g_image_dec_file_name,0,1024);
    MEMCPY(g_image_dec_file_name,file,1024);

	MEMSET(&g_image_dec_cfg, 0, sizeof(g_image_dec_cfg));

	if(mode == IMAGEDEC_REAL_SIZE)
	{
		g_image_dec_cfg.decode_mode = IMAGEDEC_REAL_SIZE;
		g_image_dec_cfg.src_top = top;
		g_image_dec_cfg.src_left = left;
		g_image_dec_cfg.src_width= width;
		g_image_dec_cfg.src_height = height;
		g_image_dec_cfg.rotate = ANG_ORI;
	}
	else if(mode == IMAGEDEC_THUMBNAIL)
	{
		g_image_dec_cfg.decode_mode = IMAGEDEC_THUMBNAIL;
		g_image_dec_cfg.dest_top = top;
		g_image_dec_cfg.dest_left = left;
		g_image_dec_cfg.dest_width= width;
		g_image_dec_cfg.dest_height = height;
		g_image_dec_cfg.rotate = ANG_ORI;
	}
    else if (mode == IMAGEDEC_MULTI_PIC)
    {
        g_image_dec_cfg.decode_mode = IMAGEDEC_MULTI_PIC;
		g_image_dec_cfg.dest_top = top;
		g_image_dec_cfg.dest_left = left;
		g_image_dec_cfg.dest_width= width;
		g_image_dec_cfg.dest_height = height;
		g_image_dec_cfg.rotate = ANG_ORI;
	}
	else if(mode == IMAGEDEC_FULL_SRN)
	{
		g_image_dec_cfg.decode_mode = IMAGEDEC_FULL_SRN;
		g_image_dec_cfg.dest_top = top;
		g_image_dec_cfg.dest_left = left;
		g_image_dec_cfg.dest_width= width;
		g_image_dec_cfg.dest_height = height;
		g_image_dec_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}
	else if(mode == IMAGEDEC_SIZEDEFINE)
	{
		g_image_dec_cfg.decode_mode = IMAGEDEC_SIZEDEFINE;
		g_image_dec_cfg.dest_top = top;
		g_image_dec_cfg.dest_left = left;
		g_image_dec_cfg.dest_width= width;
		g_image_dec_cfg.dest_height = height;
		g_image_dec_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}
	else
	{
		g_image_dec_cfg.decode_mode = IMAGEDEC_FULL_SRN;
		g_image_dec_cfg.dest_top = top;
		g_image_dec_cfg.dest_left = left;
		g_image_dec_cfg.dest_width= width;
		g_image_dec_cfg.dest_height = height;
		g_image_dec_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
	}

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_DECODE_OK,OSAL_TWF_ANDW,5000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_dec_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_OK);

	return 0;
}

int image_decode_ex(char *file, int mode, int left, int top, int width, int height, unsigned char rotate, struct image_slideshow_effect *effect)
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MEMSET(image_dec_ex_file_name,0,1024);
    MEMCPY(image_dec_ex_file_name,file,1024);

//    image_dec_ex_file_name = file;
	MEMSET(&g_image_ext_cfg, 0, sizeof(g_image_ext_cfg));

	if(mode == IMAGEDEC_REAL_SIZE)
	{
		g_image_ext_cfg.decode_mode = IMAGEDEC_REAL_SIZE;
		g_image_ext_cfg.src_top = top;
		g_image_ext_cfg.src_left = left;
		g_image_ext_cfg.src_width= width;
		g_image_ext_cfg.src_height = height;
		g_image_ext_cfg.rotate = ANG_ORI;
	}
	else if(mode == IMAGEDEC_THUMBNAIL)
	{
		g_image_ext_cfg.decode_mode = IMAGEDEC_THUMBNAIL;
		g_image_ext_cfg.dest_top = top;
		g_image_ext_cfg.dest_left = left;
		g_image_ext_cfg.dest_width= width;
		g_image_ext_cfg.dest_height = height;
		g_image_ext_cfg.rotate = ANG_ORI;
	}
    else if (mode == IMAGEDEC_MULTI_PIC)
    {
        g_image_ext_cfg.decode_mode = IMAGEDEC_MULTI_PIC;
		g_image_ext_cfg.dest_top = top;
		g_image_ext_cfg.dest_left = left;
		g_image_ext_cfg.dest_width= width;
		g_image_ext_cfg.dest_height = height;
		g_image_ext_cfg.rotate = ANG_ORI;
    }
	else
	{
		g_image_ext_cfg.decode_mode = IMAGEDEC_FULL_SRN;
		g_image_ext_cfg.dest_top = top;
		g_image_ext_cfg.dest_left = left;
		g_image_ext_cfg.dest_width= width;
		g_image_ext_cfg.dest_height = height;
		g_image_ext_cfg.rotate = (rotate < 4) ? rotate :  ANG_ORI;
		g_image_ext_cfg.effect = effect;
	}

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX_OK,OSAL_TWF_ANDW,5000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_dec_ex_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_DECODE_EX_OK);
	return 0;
}

int image_display(char * file, struct image_display_t *pdisplay)
{
	int ret;

	pdisplay->dest_top = 0;
	pdisplay->dest_left = 0;
	pdisplay->dest_width = 720;
	pdisplay->dest_height = 576;

	struct image_config *cfg = (struct image_config *)pdisplay;

	ret = image_engine_decode(file, cfg);

	return ret;
}

int image_get_info(char *filename, struct image_info *info )
{
    OSAL_ER rlt = OSAL_E_OK;
    UINT32 flgptn = 0;

    MEMSET(g_image_filename,0,1024);
    MEMCPY(g_image_filename,filename,1024);
//    g_image_filename = filename;
//    g_info = info;

    osal_flag_set(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET);
    rlt = osal_flag_wait(&flgptn,image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET_OK,OSAL_TWF_ANDW,2000);
    if(OSAL_E_OK != rlt)
    {
        IMAGE_PRINTF("image_engine_info_get_fail\n");
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET);
        osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET_OK);
        return -1;
    }
    osal_flag_clear(image_engine_flag,IMAGE_ENGINE_CMD_INFO_GET_OK);

    MEMCPY(info,&g_info,sizeof(struct image_info));

	return image_info_get_ret;
}

int image_ioctl (char *filename, UINT32 cmd, UINT32 para)
{
	int ret = 0;

	//ret = image_engine_ioctl(filename, cmd, para);

	return ret;
}

int pe_cfg(struct pe_feature_cfg *pcfg)
{
	if(!pcfg)
	{
		return -1;
	}

	MEMCPY((void*)&g_mp_feature_cfg, pcfg ,sizeof(struct pe_feature_cfg));

	return 0;
}
//################################################################################
//## wrapper for video engine

#ifdef MEDIA_PLAYER_VIDEO_SUPPORT

static int video_init(struct pe_video_cfg *pe_video_cfg)
{
	int ret;

	ret = video_engine_init(pe_video_cfg);

	return ret;
}

int video_decode(char *file, UINT8 video_stream_type, enum SndDupChannel audio_channel, BOOL preview)
{
    /*
        Note:
        video_decode() run in CPU, video_engine_decode() is a remote call in dual-cpu architecture.
        video_engine_decode() need [char *file] be global memory. malloc it here is a general
        method for all projects, include single-cpu, dual-cpu, dual-cpu with hw security enabled.
        Q: why not malloc it in video_engine_decode()?
        A: video_engine_decode() run in SEE, CPU cannot read SEE memory
                                                                       -- Jerry Long on 2010-07-08
    */
    static char *m_pe_file_name_buf = NULL;
    if (m_pe_file_name_buf == NULL)
    {
        m_pe_file_name_buf = MALLOC(2048+4); // FULL_PATH_SIZE
        ASSERT(m_pe_file_name_buf);
        MEMSET(m_pe_file_name_buf, 0, 2048+4);
    }
    STRCPY(m_pe_file_name_buf, file);

    return video_engine_decode(m_pe_file_name_buf, video_stream_type, audio_channel, preview);
}

int video_dec_file(char *path, BOOL preview)
{
#ifdef SUPPORT_ES_PLAYER
	int ret = 0;

	if((ret = network_stream_test(path, preview)) > 0)
		return ret;
#endif

#ifdef SUPPORT_MPEG4_TEST
	return video_decode(path, UNKNOWN_STREAM, SND_DUP_NONE, preview);
#else
	return video_decode(path, MPEG_12_FILE_STREAM, SND_DUP_NONE, preview);
#endif
}

#endif


#ifdef SUPPORT_MPEG4_TEST
int video_set_output(enum VDecOutputMode eOutMode, struct VDecPIPInfo *pInitInfo)
{
    return video_engine_set_output(eOutMode, pInitInfo);
}
#endif
#ifdef MORETV_PLUGIN_SUPPORT
UINT8 pe_inited = 0;
struct pe_music_cfg pe_music_cfg_bk;
struct pe_image_cfg pe_image_cfg_bk;
struct pe_video_cfg pe_video_cfg_bk;
#endif

//########################################################################################
//## PE functions
int pe_init(struct pe_music_cfg *pe_music_cfg, struct pe_image_cfg *pe_image_cfg, struct pe_video_cfg *pe_video_cfg)
{
	int image_ret, music_ret, video_ret;


	if((NULL==pe_music_cfg)||(NULL==pe_image_cfg)||(NULL==pe_video_cfg))
	{
		return -1;
	}

	memset(&g_pe_music_cfg,0,sizeof(pe_music_cfg));

	//if app dont init this addr,then default config add by system
	if((0==pe_music_cfg->pe_cache_buf_start_addr)||(0==pe_music_cfg->pe_cache_buf_len))
	{
		pe_music_cfg->pe_cache_buf_len=MUSIC_PE_CACHE_SIZE_MAX;
		pe_music_cfg->pe_cache_buf_start_addr=MALLOC(pe_music_cfg->pe_cache_buf_len);
		if(NULL==pe_music_cfg->pe_cache_buf_start_addr)
		{
			return -1;
		}
		g_pe_music_cfg.pe_cache_buf_start_addr=pe_music_cfg->pe_cache_buf_start_addr;
		g_pe_music_cfg.pe_cache_buf_len=pe_music_cfg->pe_cache_buf_len;
	}


#ifdef MORETV_PLUGIN_SUPPORT
	//bk params
	MEMCPY(&pe_music_cfg_bk, pe_music_cfg, sizeof(struct pe_music_cfg));
	MEMCPY(&pe_image_cfg_bk, pe_image_cfg, sizeof(struct pe_image_cfg));
	MEMCPY(&pe_video_cfg_bk, pe_video_cfg, sizeof(struct pe_video_cfg));
	pe_inited = 1;
#endif
	if(pe_init_time !=0)
	{
		MEMSET((void*)&g_mp_feature_cfg, 0 ,sizeof(struct pe_feature_cfg));
		pe_init_time++;
		return 0;
	}

	MEMSET((void*)&g_mp_feature_cfg, 0 ,sizeof(struct pe_feature_cfg));
	//init the image decoder
	image_ret = image_init(pe_image_cfg);
	if (image_ret == -1)
	{
		return image_ret;
	}
	//init the music decoder
	music_ret = music_init(pe_music_cfg);
	if (music_ret == -1)
	{
		//image_cleanup();
	}

#ifdef MEDIA_PLAYER_VIDEO_SUPPORT

    video_ret = video_init(pe_video_cfg);
    if (video_ret == -1)
    {
		//image_cleanup();
		//music_release();
    }


#endif
#ifdef MP4_CONTAINER
	av_player_config player_config;
	MEMSET((void *)&player_config, 0, sizeof(av_player_config));
	player_config.buf_start1 =AVP_BUF1_ADDR;//__MM_PVR_VOB_BUFFER_ADDR + 0XA00000;//__MM_FB_TOP_ADDR-0x2000000;// AVP_BUF1_ADDR;
	player_config.buf_size1 = AVP_BUF1_LEN;//0x1400000;//AVP_BUF2_LEN;//#define AVP_BUF1_LEN   0xF00000 //15M
	player_config.buf_start2 = AVP_BUF2_ADDR;//__MM_FB_TOP_ADDR - 0x2300000;//AVP_BUF2_ADDR;//0xA2000000;//pe_image_cfg->frm_y_addr;
	player_config.buf_size2 = AVP_BUF2_LEN;//0x2300000;//0xE00000;//0x2000000;//(pe_image_cfg->frm_y_size + pe_image_cfg->frm_c_size)<<2;#define AVP_BUF2_LEN   0x1400000//20M
	avp_cache_init(__MM_MP_BUFFER_ADDR);//
	av_player_init(&player_config);
	g_mp4_av_player_handle = av_player_create();
#endif

#ifdef ENABLE_PE_CACHE
	pe_cache_init();

	pe_cache_cb_fp fp;

#ifdef NETWORK_SUPPORT//net work

	fp.file_open = url_open;
	fp.file_close = url_close;
	fp.file_eof = NULL;
	fp.file_read = url_read;
	fp.file_seek = NULL;
	fp.file_tell = NULL;
	pe_cache_register_net_fp(fp,PE_NET_FILE_TYPE_URL);
#endif

#ifdef SUPPORT_ES_PLAYER
	fp.file_open = ali_stream_open;
	fp.file_close = ali_stream_close;
	fp.file_eof = ali_stream_end;
	fp.file_read = ali_stream_read;
	fp.file_seek = ali_stream_seek;
	fp.file_tell = ali_stream_tell;
	pe_cache_register_net_fp(fp,PE_ALI_SPECIAL_STREAM);
#endif

#endif

	if(image_ret == 0 && (music_ret == 0 || video_ret == 0))
		pe_init_time++;
	return (music_ret||video_ret);
}

int pe_cleanup()
{
	//release the image decoder
	#if 1
	//don't release pe when usb plug out
	if(pe_init_time==1)
	{
		image_cleanup();
		//release the music decoder
		music_release();
		pe_init_time=0;
		mpg_cmd_stop_proc();

	    pe_cache_release();
	}
	else
	{
	    if(pe_init_time!=0)
    		pe_init_time--;
		//do nothing some module still need pe
	}

	if(NULL!=g_pe_music_cfg.pe_cache_buf_start_addr)
	{
		g_pe_music_cfg.pe_cache_buf_len=0;
		FREE(g_pe_music_cfg.pe_cache_buf_start_addr);
		g_pe_music_cfg.pe_cache_buf_start_addr=NULL;
	}
	#else

	image_cleanup();
	//release the music decoder
	music_release();
	#endif
}
#ifdef MORETV_PLUGIN_SUPPORT
int pe_reinit()
{
	///if(pe_inited)
		pe_init(&pe_music_cfg_bk, &pe_image_cfg_bk, &pe_video_cfg_bk);
	return 0;
}
#endif

int get_file_name_ext(const char *filename, char *pext, int ext_size)
{
    int file_name_len;
    int i;
    file_name_len = strlen(filename);

    if (file_name_len <= 3)
    {
        *pext = 0;
        return 0;
    }
    for ( i = file_name_len; i; i--)
    {
        if (filename[i-1] == '.')
            break;
    }

    if (i == 0)
    {
        *pext = 0;
        return 0;
    }

    strncpy(pext, &filename[i], ext_size - 1);
    for (i = 0; pext[i]; i++)
    {
        if (pext[i] >= 'A' && pext[i] <= 'Z')
        {
            pext[i] |= 0x20;
        }
    }

    return i;
}

